package com.example.palette.start;

import android.content.Context;
import android.os.Looper;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger;

public class StartTaskManager {
    private CountDownLatch countDownLatch;
    private Context context;
    private List<IStartTask<?>> startTaskList;
    private StartTaskCenter startTaskCenter;

    public StartTaskManager(Context context, List<IStartTask<?>> startTaskList,CountDownLatch countDownLatch) {
        this.context = context;
        this.startTaskList = startTaskList;
        this.countDownLatch = countDownLatch;
    }

    public StartTaskManager start(){
        if(Looper.myLooper() != Looper.getMainLooper()){
            throw new RuntimeException("start must be executed in main thread");
        }
        startTaskCenter = StartTaskSorter.sort(startTaskList);
        for(IStartTask startTask:startTaskCenter.getSortResult()){
            StartTaskRunnable startTaskRunnable = new StartTaskRunnable(context,startTask,this);
            if(startTask.inMainThread()){
                startTaskRunnable.run();
            }else {
                startTask.executor().execute(startTaskRunnable);
            }
        }
        return this;
    }

    public void notifyChilds(IStartTask startTask) {
        if(!startTask.inMainThread() && startTask.mainThreadWait()){
            countDownLatch.countDown();
        }
        Map<Class<? extends IStartTask>, List<Class<? extends IStartTask>>> depends = startTaskCenter.getStartTaskDepends();
        if(depends.containsKey(startTask.getClass())){
            List<Class<? extends IStartTask>> list = depends.get(startTask.getClass());
            for (Class<? extends IStartTask> clazz : list){
                IStartTask iStartTask = startTaskCenter.getStartTask().get(clazz);
                iStartTask.toNotify();
            }
        }
    }

    public void allWait(){
        try {
            countDownLatch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public static class Buider{
        private List<IStartTask<?>> startTasks = new ArrayList<>();

        public Buider addStartTask(IStartTask<?> startTask){
            startTasks.add(startTask);
            return this;
        }

        public Buider addStartTasks(List<IStartTask<?>> startTasks){
            startTasks.addAll(startTasks);
            return this;
        }

        public StartTaskManager build(Context context){
            AtomicInteger atomicInteger = new AtomicInteger();
            for(IStartTask startTask:startTasks){
                if(!startTask.inMainThread() && startTask.mainThreadWait()){
                    atomicInteger.incrementAndGet();
                }
            }
            CountDownLatch countDownLatch = new CountDownLatch(atomicInteger.get());
            return new StartTaskManager(context,startTasks,countDownLatch);
        }
    }
}
